package net.kleinhenz.questor.game;

import java.io.File;
import java.io.IOException;
import java.net.URL;

import android.content.Context;

import net.kleinhenz.questor.exceptions.QuestMLException;
import net.kleinhenz.questor.model.Player;
import net.kleinhenz.questor.model.Quest;
import net.kleinhenz.questor.model.Station;
import net.kleinhenz.questor.system.QSRFile;
import net.kleinhenz.questor.ui.StoryActivity;

/**
 * This class implements all global operations of a running game.
 * It holds references to the player as well as the quest.
 * 
 * @author Michael Kleinhenz, m.kleinhenz@tarent.de
 *
 */
public class Game
{
	private Context appContext = null;
	private Player currentPlayer = null;
	private Quest currentQuest = null;
	private Rules currentRules = null;
	private QSRFile currentQSR = null;
	private Station currentStation = null;
	private StoryActivity currentStoryActivity = null;
	
	public Game(Context appContext)
	{
		if (appContext==null)
			throw new RuntimeException("Application context must not be null.");
		this.appContext = appContext;
	}
	
	public void loadGame(URL url) throws Exception
	{
		if (url==null)
			throw new RuntimeException("Game URL must not be null.");
				
		if (url.getProtocol().equals("file") && url.getAuthority()!=null && url.getAuthority().equals("assets"))
		{
        	String filePath = url.getFile().replaceFirst("/", "");

        	// load quest
    		try
    		{
    			setCurrentQSR(new QSRFile(appContext.getCacheDir(), appContext.getAssets().open(filePath)));
    		}
    		catch (IOException e)
    		{
    			throw new RuntimeException(e);
    		}
		}
		else if (url.getProtocol().equals("file"))
		{
			String filePath = url.getFile();

        	// load quest
    		try
    		{
    			setCurrentQSR(new QSRFile(appContext.getCacheDir(), new File(filePath)));
    		}
    		catch (IOException e)
    		{
    			throw new RuntimeException(e);
    		}
		}
		else
			throw new RuntimeException("Protocol " + url.getProtocol() + " is not supported for game loading.");


		// retrieve qml from file
		try
		{
			setCurrentQuest(getCurrentQSR().getStory());
		}
		catch (IOException e)
		{
			throw new RuntimeException(e);
		}
		catch (QuestMLException e)
		{
			throw new RuntimeException(e);
		}			

		// Create rules system
		setCurrentRules(RulesFactory.getRules(getCurrentQuest().getRules()));
		
		// copy player type to this game
		setPlayer(getCurrentRules().createPlayer(getCurrentQuest().getPlayer()));
		
		// start game on root station
		setCurrentStation(getCurrentQuest().getRoot());	
	}
	
	public void setPlayer(Player currentPlayer)
	{
		this.currentPlayer = currentPlayer;
	}

	public Player getPlayer()
	{
		return this.currentPlayer;
	}
	
	public Quest getCurrentQuest()
	{
		return currentQuest;
	}

	public void setCurrentQuest(Quest currentQuest)
	{
		this.currentQuest = currentQuest;
	}

	public void setCurrentQSR(QSRFile currentQSR)
	{
		this.currentQSR = currentQSR;
	}

	public QSRFile getCurrentQSR()
	{
		return currentQSR;
	}

	public void setCurrentRules(Rules currentRules)
	{
		this.currentRules = currentRules;
	}

	public Rules getCurrentRules()
	{
		return currentRules;
	}

	public Station getCurrentStation()
	{
		return currentStation;
	}

	public void setCurrentStation(Station currentStation)
	{
		this.currentStation = currentStation;
		if (currentStoryActivity!=null)
			currentStoryActivity.goTo(currentStation);
	}

	public StoryActivity getCurrentStoryActivity()
	{
		return currentStoryActivity;
	}

	public void setCurrentStoryActivity(StoryActivity currentStoryActivity)
	{
		this.currentStoryActivity = currentStoryActivity;
	}
	
	public void save(String saveId)
	{
		// FIXME: save quest, qsr, station
		getPlayer().save(saveId);
	}
	
	public void delete(String saveId)
	{
		// FIXME: delete savegame
		getPlayer().delete(saveId);
	}

	public void load(String saveId)
	{
		// FIXME: load savegame
		getPlayer().load(saveId);
	}
}
